//AUTHOR: Josh High
//COURSE: ISTM 415.502 
//FORM: JasperGreenContext.cs 
//PURPOSE: Defines the DbContext for the JasperGreen application, including DbSets for entities like Property, Customer, Employee, Crew, etc.
//INITIALIZE: Set up Entity Framework Core to work with the database. This context is used to access and manage the data within the database.
//INPUT: Accepts data model classes that represent entities to be stored in the database.
//PROCESS: Provides access to the database tables through DbSet properties and manages the connection to the database. Supports CRUD operations through controllers.
//OUTPUT: Serves as the bridge between the application’s data models and the database using Entity Framework Core’s ORM functionality.
//TERMINATE: Managed by Entity Framework Core’s lifecycle during application runtime and session. The connection is automatically closed when no longer needed.
//HONOR CODE: “On my honor, as an Aggie, I have neither given
// nor received unauthorized aid on this academic
// work.”

using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Reflection.Emit;

namespace JasperGreenTeam11.Models
{
    public class JasperGreenContext : DbContext
    {
        public JasperGreenContext(DbContextOptions<JasperGreenContext> options) : base(options) { }

        public DbSet<Customer> Customers { get; set; }
        public DbSet<Property> Properties { get; set; }
        public DbSet<Employee> Employees { get; set; }
        public DbSet<Crew> Crews { get; set; }

        public DbSet<ProvideService> ProvideService { get; set; }
        public DbSet<Payment> Payments { get; set; }
       
        
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Customer>().HasData(
                new Customer { CustomerId = 1, FirstName = "John", LastName = "Doe", Email = "john@example.com", Phone = "555-1234" },
                new Customer { CustomerId = 2, FirstName = "Jane", LastName = "Smith", Email = "jane@example.com", Phone = "555-5678" },
                new Customer { CustomerId = 3, FirstName = "Alice", LastName = "Brown", Email = "alice@example.com", Phone = "555-8765" },
                new Customer { CustomerId = 4, FirstName = "Bob", LastName = "Green", Email = "bob@example.com", Phone = "555-4321" },
                new Customer { CustomerId = 5, FirstName = "Charlie", LastName = "White", Email = "charlie@example.com", Phone = "555-9876" }
            );

            // Prevent cascading deletes between Customer and Property
            modelBuilder.Entity<Property>()
             .HasOne(p => p.Customer)
             .WithMany(c => c.Properties)
             .HasForeignKey(p => p.CustomerId)
             .OnDelete(DeleteBehavior.Restrict);

            modelBuilder.Entity<Property>().HasData(
                new Property { PropertyId = 1, Address = "123 Greenway Blvd", CustomerId = 1 },
                new Property { PropertyId = 2, Address = "456 Elm St", CustomerId = 1 },
                new Property { PropertyId = 3, Address = "789 Oak Dr", CustomerId = 2 },
                new Property { PropertyId = 4, Address = "101 Maple Ave", CustomerId = 3 },
                new Property { PropertyId = 5, Address = "222 Cedar Rd", CustomerId = 4 },
                new Property { PropertyId = 6, Address = "333 Pine Ln", CustomerId = 5 },
                new Property { PropertyId = 7, Address = "444 Birch Pl", CustomerId = 2 },
                new Property { PropertyId = 8, Address = "555 Walnut Ct", CustomerId = 3 },
                new Property { PropertyId = 9, Address = "666 Aspen Trl", CustomerId = 4 },
                new Property { PropertyId = 10, Address = "777 Willow Way", CustomerId = 5 }
            );

            modelBuilder.Entity<Crew>().HasData(
                new Crew { CrewId = 1, CrewName = "Green Team A" },
                new Crew { CrewId = 2, CrewName = "Landscapers B" },
                new Crew { CrewId = 3, CrewName = "Maintenance Crew C" },
                new Crew { CrewId = 4, CrewName = "Tree Trimmers D" },
                new Crew { CrewId = 5, CrewName = "Lawn Care E" }
            );

            modelBuilder.Entity<Employee>().HasData(
                new Employee { EmployeeId = 1, FirstName = "Ethan", LastName = "Wilson", CrewId = 1 },
                new Employee { EmployeeId = 2, FirstName = "Sophia", LastName = "Davis", CrewId = 1 },
                new Employee { EmployeeId = 3, FirstName = "Michael", LastName = "Johnson", CrewId = 2 },
                new Employee { EmployeeId = 4, FirstName = "Olivia", LastName = "Martinez", CrewId = 2 },
                new Employee { EmployeeId = 5, FirstName = "Daniel", LastName = "Brown", CrewId = 3 },
                new Employee { EmployeeId = 6, FirstName = "Emma", LastName = "Anderson", CrewId = 3 },
                new Employee { EmployeeId = 7, FirstName = "James", LastName = "White", CrewId = 4 },
                new Employee { EmployeeId = 8, FirstName = "Isabella", LastName = "Thompson", CrewId = 4 },
                new Employee { EmployeeId = 9, FirstName = "Benjamin", LastName = "Lewis", CrewId = 5 },
                new Employee { EmployeeId = 10, FirstName = "Charlotte", LastName = "Hall", CrewId = 5 },
                new Employee { EmployeeId = 11, FirstName = "Mason", LastName = "Scott", CrewId = 1 },
                new Employee { EmployeeId = 12, FirstName = "Liam", LastName = "Clark", CrewId = 2 },
                new Employee { EmployeeId = 13, FirstName = "Ava", LastName = "Young", CrewId = 3 },
                new Employee { EmployeeId = 14, FirstName = "William", LastName = "Hernandez", CrewId = 4 },
                new Employee { EmployeeId = 15, FirstName = "Emily", LastName = "King", CrewId = 5 }
            );

            // One-to-Many: Employee -> Crew
            modelBuilder.Entity<Employee>()
                .HasOne(e => e.Crew)
                .WithMany(c => c.Employees)
                .HasForeignKey(e => e.CrewId);

            // Define precision for decimal fields
            modelBuilder.Entity<ProvideService>()
                .Property(p => p.Price)
                .HasPrecision(18, 2);  // 18 total digits, 2 after decimal

            modelBuilder.Entity<Payment>()
                .Property(p => p.Amount)
                .HasPrecision(18, 2);  // 18 total digits, 2 after decimal

            modelBuilder.Entity<Crew>()
         .HasOne(c => c.CrewForeman)
         .WithMany(e => e.CrewForeman)
         .HasForeignKey(c => c.CrewForemanID)
         .OnDelete(DeleteBehavior.Restrict);

            modelBuilder.Entity<Crew>()
                .HasOne(c => c.CrewMember1)
                .WithMany(e => e.CrewMember1)
                .HasForeignKey(c => c.CrewMember1ID)
                .OnDelete(DeleteBehavior.Restrict);

            modelBuilder.Entity<Crew>()
                .HasOne(c => c.CrewMember2)
                .WithMany(e => e.CrewMember2)
                .HasForeignKey(c => c.CrewMember2ID)
                .OnDelete(DeleteBehavior.Restrict);

            // Seeding ProvideService Data
            modelBuilder.Entity<ProvideService>().HasData(
                new ProvideService { ProvideServiceId = 1, PropertyId = 1, CrewId = 1, ServiceType = "Lawn Mowing", Price = 50.00m, ServiceDate = new DateTime(2024, 03, 15) },
                new ProvideService { ProvideServiceId = 2, PropertyId = 2, CrewId = 1, ServiceType = "Tree Pruning", Price = 75.00m, ServiceDate = new DateTime(2024, 03, 15) },
                new ProvideService { ProvideServiceId = 3, PropertyId = 3, CrewId = 2, ServiceType = "Garden Maintenance", Price = 100.00m, ServiceDate = new DateTime(2024, 03, 15) },
                new ProvideService { ProvideServiceId = 4, PropertyId = 4, CrewId = 2, ServiceType = "Seasonal Cleanup", Price = 120.00m, ServiceDate = new DateTime(2024, 03, 15) },
                new ProvideService { ProvideServiceId = 5, PropertyId = 5, CrewId = 3, ServiceType = "Lawn Fertilization", Price = 80.00m, ServiceDate = new DateTime(2024, 03, 15) },
                new ProvideService { ProvideServiceId = 6, PropertyId = 6, CrewId = 3, ServiceType = "Lawn Mowing", Price = 50.00m, ServiceDate = new DateTime(2024, 03, 15) },
                new ProvideService { ProvideServiceId = 7, PropertyId = 7, CrewId = 4, ServiceType = "Mulching", Price = 90.00m, ServiceDate = new DateTime(2024, 03, 15) },
                new ProvideService { ProvideServiceId = 8, PropertyId = 8, CrewId = 4, ServiceType = "Pest Control", Price = 110.00m, ServiceDate = new DateTime(2024, 03, 15) },
                new ProvideService { ProvideServiceId = 9, PropertyId = 9, CrewId = 5, ServiceType = "Tree Pruning", Price = 75.00m, ServiceDate = new DateTime(2024, 03, 15) },
                new ProvideService { ProvideServiceId = 10, PropertyId = 10, CrewId = 5, ServiceType = "Garden Design", Price = 200.00m, ServiceDate = new DateTime(2024, 03, 15) }
            );

            // Seeding Payment Data
            modelBuilder.Entity<Payment>().HasData(
                new Payment { PaymentId = 1, CustomerId = 1, Amount = 150.00m, Date = new DateTime(2024, 03, 15), PaymentMethod = "Credit Card" },
                new Payment { PaymentId = 2, CustomerId = 2, Amount = 200.00m, Date = new DateTime(2024, 03, 15), PaymentMethod = "PayPal" },
                new Payment { PaymentId = 3, CustomerId = 3, Amount = 100.00m, Date = new DateTime(2024, 03, 15), PaymentMethod = "Debit Card" },
                new Payment { PaymentId = 4, CustomerId = 4, Amount = 250.00m, Date = new DateTime(2024, 03, 15), PaymentMethod = "Bank Transfer" },
                new Payment { PaymentId = 5, CustomerId = 5, Amount = 180.00m, Date = new DateTime(2024, 03, 15), PaymentMethod = "Cash" }
            );
        }
    }
}
